ETAPA 3: UNIÓN DE DATOS Y SELECCIÓN DE VARIABLES¶

In [1]:
# Dependencias básicas
import pandas as pd
import numpy as np
import itertools

# Dependencias de visualización
from matplotlib import pyplot as plt
import seaborn as sns
import altair as alt
# Desactivar el límite de máximo por defecto de 5,000 filas para las visulizaciones con la librería Altair
alt.data_transformers.disable_max_rows()

# Despendencias estadísticas
import scipy.stats as stats
#!pip install scikit-posthocs
import scikit_posthocs as sp

Importar Dataframes¶

In [2]:
# Importación de datasets
inmigrantes_data = pd.read_csv("../13 - Exports (preprocesamiento)/top_inmigracion_2008_2022.csv")
indices_democracia = pd.read_csv("../13 - Exports (preprocesamiento)/indices_democracia.csv")
indices_desarrollo = pd.read_csv("../13 - Exports (preprocesamiento)/indices_desarrollo.csv")
regiones = pd.read_csv("../13 - Exports (preprocesamiento)/continentes_regiones.csv")
libertad = pd.read_csv("../13 - Exports (preprocesamiento)/libertad.csv")
conflictos_armados = pd.read_csv("../13 - Exports (preprocesamiento)/muertes_conflictos_armados.csv")
residentes = pd.read_csv("../13 - Exports (preprocesamiento)/residentes.csv")
regimen_politico = pd.read_csv("../13 - Exports (preprocesamiento)/regimen_politico.csv")
homicidios = pd.read_csv("../13 - Exports (preprocesamiento)/tasa_homicidios.csv")
turismo = pd.read_csv("../13 - Exports (preprocesamiento)/turismo.csv")
In [3]:
# Lista con todos los df
dataframes = [inmigrantes_data, indices_democracia, indices_desarrollo, regiones, libertad, conflictos_armados, residentes, regimen_politico, homicidios, turismo]

# Funcion para obtener el nombre de cada dataframe
def get_df_name(df):
    name =[x for x in globals() if globals()[x] is df][0]
    return name

# Bucle para mostrar por pantalla cada dataframe
with pd.option_context('expand_frame_repr', False): # expandir las columnas del output
    for df in dataframes:
        print (f'------------->>>>>>>>>>> {get_df_name(df)} <<<<<<<<<<<<----------------\n')
        print (df)
        print ('\n')
------------->>>>>>>>>>> inmigrantes_data <<<<<<<<<<<<----------------

      Year Nationality code      Sex Age group  Immigrant count
0     2008              DZA     Both    0 - 14              759
1     2008              PER    Males   35 - 44             2938
2     2008              PER    Males   45 - 54             1128
3     2008              PER    Males   55 - 64              265
4     2008              PER    Males       65+              156
...    ...              ...      ...       ...              ...
9355  2022              PAK    Males   55 - 64              330
9356  2022              PAK  Females   55 - 64              146
9357  2022              PAK     Both       65+              169
9358  2022              PAK    Males       65+               99
9359  2022              PAK  Females       65+               70

[9360 rows x 5 columns]


------------->>>>>>>>>>> indices_democracia <<<<<<<<<<<<----------------

    Nationality code  Year  Liberal democracy index  Deliberative democracy index
0                DZA  2008                    0.164                         0.249
1                DZA  2009                    0.163                         0.246
2                DZA  2010                    0.162                         0.250
3                DZA  2011                    0.162                         0.250
4                DZA  2012                    0.165                         0.252
..               ...   ...                      ...                           ...
400              VEN  2018                    0.060                         0.040
401              VEN  2019                    0.059                         0.041
402              VEN  2020                    0.057                         0.040
403              VEN  2021                    0.060                         0.045
404              VEN  2022                    0.056                         0.044

[405 rows x 4 columns]


------------->>>>>>>>>>> indices_desarrollo <<<<<<<<<<<<----------------

     Year Nationality code  Unemployment %  Political and Violence Percentile  Probability of dying young  Regulatory Quality Percentile  Rule of Law Percentile  Voice and Accountability Percentile  Salaried workers %  GDP_growth  Inflation_annual
0    2008              DZA           11.33                              14.90                         3.7                          29.13                   24.52                                20.67               67.41        2.40             15.31
1    2008              ARG            7.84                              40.87                         4.8                          24.76                   27.88                                58.17               76.32        4.06             23.17
2    2008              BRA            8.27                              33.65                         8.1                          54.37                   46.63                                63.94               66.28        5.09              8.78
3    2008              BGR            5.61                              56.25                         3.7                          73.30                   51.92                                65.87               87.60        6.13              8.10
4    2008              CHN            4.59                              29.33                         2.9                          48.54                   37.98                                 5.77               45.96        9.65              7.80
..    ...              ...             ...                                ...                         ...                            ...                     ...                                  ...                 ...         ...               ...
400  2022              ESP           12.92                              53.30                         1.5                          75.94                   77.36                                79.71               84.66        5.77              4.14
401  2022              UKR           33.30                               5.66                        18.1                          40.57                   18.87                                45.89               82.40      -29.10             34.32
402  2022              GBR            3.73                              62.26                         1.7                          93.40                   89.15                                89.37               84.33        4.35              5.15
403  2022              USA            3.65                              45.28                         6.2                          91.04                   88.68                                72.95               93.72        1.94              7.04
404  2022              VEN            5.62                              12.26                        15.5                           2.36                    0.47                                 6.76               59.85        8.00           1203.15

[405 rows x 11 columns]


------------->>>>>>>>>>> regiones <<<<<<<<<<<<----------------

   Continent                     Sub-region Nationality code
0     Europe                 European Union              BGR
1     Europe                 European Union              FRA
2     Europe                 European Union              ITA
3     Europe                 European Union              PRT
4     Europe                 European Union              DEU
5     Europe                 European Union              ROU
6     Europe                 Rest of Europe              GBR
7     Europe                 Rest of Europe              UKR
8     Europe                 Rest of Europe              RUS
9     Africa                         Africa              DZA
10    Africa                         Africa              MAR
11    Africa                         Africa              SEN
12   America                  North America              USA
13   America  Central America and Caribbean              CUB
14   America  Central America and Caribbean              HND
15   America  Central America and Caribbean              NIC
16   America  Central America and Caribbean              DOM
17   America                  South America              ARG
18   America                  South America              BRA
19   America                  South America              COL
20   America                  South America              ECU
21   America                  South America              PRY
22   America                  South America              PER
23   America                  South America              VEN
24      Asia                           Asia              CHN
25      Asia                           Asia              PAK


------------->>>>>>>>>>> libertad <<<<<<<<<<<<----------------

    Country code  Year  Absence of Corruption  Civil Liberties  Educational equality  Health equality  Judicial accountability  Public sector corrupt exchanges
0            ARG  2008                   0.51             0.80                  0.56             0.62                     0.37                             0.46
1            ARG  2009                   0.51             0.80                  0.56             0.62                     0.37                             0.46
2            ARG  2010                   0.51             0.80                  0.56             0.62                     0.37                             0.46
3            ARG  2011                   0.51             0.80                  0.56             0.62                     0.37                             0.46
4            ARG  2012                   0.49             0.80                  0.56             0.62                     0.37                             0.46
..           ...   ...                    ...              ...                   ...              ...                      ...                              ...
385          VEN  2018                   0.06             0.39                  0.23             0.18                     0.01                             0.00
386          VEN  2019                   0.06             0.37                  0.18             0.18                     0.01                             0.00
387          VEN  2020                   0.00             0.37                  0.13             0.18                     0.12                             0.00
388          VEN  2021                   0.00             0.37                  0.17             0.18                     0.07                             0.00
389          VEN  2022                   0.00             0.37                  0.13             0.05                     0.07                             0.00

[390 rows x 8 columns]


------------->>>>>>>>>>> conflictos_armados <<<<<<<<<<<<----------------

    Nationality code  Year  One-sided violence_deaths  Non-state_deaths  Intrastate_deaths  Interstate_deaths
0                DZA  2008                          0                 0                345                  0
1                DZA  2009                         36                 0                508                  0
2                DZA  2010                          0                 0                236                  0
3                DZA  2011                          0                 0                261                  0
4                DZA  2012                          0                 0                258                  0
..               ...   ...                        ...               ...                ...                ...
400              VEN  2018                         89                 0                  2                  0
401              VEN  2019                         78                 0                  7                  0
402              VEN  2020                          0                 0                  0                  0
403              VEN  2021                          0                 0                  3                  0
404              VEN  2022                          0                 2                  0                  0

[405 rows x 6 columns]


------------->>>>>>>>>>> residentes <<<<<<<<<<<<----------------

     Country Code  Year      Sex  Number of residents
0             DEU  2022     Both               116122
1             DEU  2021     Both               109556
2             DEU  2020     Both               111937
3             DEU  2019     Both               111911
4             DEU  2018     Both               111495
...           ...   ...      ...                  ...
1945          PAK  2002  Females                 1521
1946          PAK  2001  Females                 1138
1947          PAK  2000  Females                  882
1948          PAK  1999  Females                  740
1949          PAK  1998  Females                  572

[1950 rows x 4 columns]


------------->>>>>>>>>>> regimen_politico <<<<<<<<<<<<----------------

    Nationality code  Year  Political regime
0                DZA  2008                 3
1                DZA  2009                 3
2                DZA  2010                 3
3                DZA  2011                 3
4                DZA  2012                 3
..               ...   ...               ...
400              VEN  2018                 1
401              VEN  2019                 1
402              VEN  2020                 1
403              VEN  2021                 1
404              VEN  2022                 1

[405 rows x 3 columns]


------------->>>>>>>>>>> homicidios <<<<<<<<<<<<----------------

     Year Nationality code  Homicide Rate
0    2008              ARG           5.89
1    2008              BGR           2.24
2    2008              BRA          26.02
3    2008              CHN           1.11
4    2008              COL          36.84
..    ...              ...            ...
393  2022              UKR           3.86
394  2015              SEN           0.27
395  2020              NIC           9.37
396  2022              NIC          11.40
397  2015              DOM          16.48

[398 rows x 3 columns]


------------->>>>>>>>>>> turismo <<<<<<<<<<<<----------------

    Year  Number of Turist
0   2000          34380000
1   2001          35330000
2   2002          34950000
3   2003          36920000
4   2004          38520000
5   2005          40730000
6   2006          42450000
7   2007          44320000
8   2008          44400000
9   2009          40230000
10  2010          40560000
11  2011          44610000
12  2012          46160000
13  2013          48760000
14  2014          51820000
15  2015          54280000
16  2016          60340000
17  2017          66640000
18  2018          67550000
19  2019          68690000
20  2020          13660000
21  2021          24430000
22  2022          59310000
23  2023          69560000


Merge dataframes en el conjunto de datos de inmigración¶

In [4]:
# Hacer una copia de datos de inmigrantes para los merge
inmigrantes = inmigrantes_data.copy()
inmigrantes
Out[4]:
Year Nationality code Sex Age group Immigrant count
0 2008 DZA Both 0 - 14 759
1 2008 PER Males 35 - 44 2938
2 2008 PER Males 45 - 54 1128
3 2008 PER Males 55 - 64 265
4 2008 PER Males 65+ 156
... ... ... ... ... ...
9355 2022 PAK Males 55 - 64 330
9356 2022 PAK Females 55 - 64 146
9357 2022 PAK Both 65+ 169
9358 2022 PAK Males 65+ 99
9359 2022 PAK Females 65+ 70

9360 rows × 5 columns

In [5]:
# Renombrar columna de codigo de país como el df "inmigrantes"
residentes.rename({'Country Code' : 'Nationality code'}, 
                  inplace = True, 
                  axis = 1)

libertad.rename({'Country code' : 'Nationality code'}, 
                inplace = True, 
                axis = 1)

# Merge cada df en "inmigrantes"
inmigrantes_merge = inmigrantes.merge(indices_desarrollo, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(indices_democracia, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(regiones, on = ['Nationality code'], how = 'left')\
                               .merge(libertad, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(conflictos_armados, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(residentes, on = ['Year', 'Nationality code', 'Sex'], how = 'left')\
                               .merge(regimen_politico, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(homicidios, on = ['Year', 'Nationality code'], how = 'left')\
                               .merge(turismo, on = ['Year'], how = 'left')\

inmigrantes_merge.info()
inmigrantes_merge.iloc[:, :15]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9360 entries, 0 to 9359
Data columns (total 32 columns):
 #   Column                               Non-Null Count  Dtype  
---  ------                               --------------  -----  
 0   Year                                 9360 non-null   int64  
 1   Nationality code                     9360 non-null   object 
 2   Sex                                  9360 non-null   object 
 3   Age group                            9360 non-null   object 
 4   Immigrant count                      9360 non-null   int64  
 5   Unemployment %                       9360 non-null   float64
 6   Political and Violence Percentile    9360 non-null   float64
 7   Probability of dying young           9360 non-null   float64
 8   Regulatory Quality Percentile        9360 non-null   float64
 9   Rule of Law Percentile               9360 non-null   float64
 10  Voice and Accountability Percentile  9360 non-null   float64
 11  Salaried workers %                   9360 non-null   float64
 12  GDP_growth                           9360 non-null   float64
 13  Inflation_annual                     9360 non-null   float64
 14  Liberal democracy index              9360 non-null   float64
 15  Deliberative democracy index         9360 non-null   float64
 16  Continent                            9360 non-null   object 
 17  Sub-region                           9360 non-null   object 
 18  Absence of Corruption                9360 non-null   float64
 19  Civil Liberties                      9360 non-null   float64
 20  Educational equality                 9360 non-null   float64
 21  Health equality                      9360 non-null   float64
 22  Judicial accountability              9360 non-null   float64
 23  Public sector corrupt exchanges      9360 non-null   float64
 24  One-sided violence_deaths            9360 non-null   int64  
 25  Non-state_deaths                     9360 non-null   int64  
 26  Intrastate_deaths                    9360 non-null   int64  
 27  Interstate_deaths                    9360 non-null   int64  
 28  Number of residents                  9360 non-null   int64  
 29  Political regime                     9360 non-null   int64  
 30  Homicide Rate                        9024 non-null   float64
 31  Number of Turist                     9360 non-null   int64  
dtypes: float64(18), int64(9), object(5)
memory usage: 2.3+ MB
Out[5]:
Year Nationality code Sex Age group Immigrant count Unemployment % Political and Violence Percentile Probability of dying young Regulatory Quality Percentile Rule of Law Percentile Voice and Accountability Percentile Salaried workers % GDP_growth Inflation_annual Liberal democracy index
0 2008 DZA Both 0 - 14 759 11.33 14.90 3.7 29.13 24.52 20.67 67.41 2.40 15.31 0.164
1 2008 PER Males 35 - 44 2938 4.03 17.31 5.1 61.65 25.96 52.40 44.47 9.13 1.10 0.649
2 2008 PER Males 45 - 54 1128 4.03 17.31 5.1 61.65 25.96 52.40 44.47 9.13 1.10 0.649
3 2008 PER Males 55 - 64 265 4.03 17.31 5.1 61.65 25.96 52.40 44.47 9.13 1.10 0.649
4 2008 PER Males 65+ 156 4.03 17.31 5.1 61.65 25.96 52.40 44.47 9.13 1.10 0.649
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
9355 2022 PAK Males 55 - 64 330 5.60 6.60 5.8 20.28 25.00 25.12 42.14 4.71 13.96 0.234
9356 2022 PAK Females 55 - 64 146 5.60 6.60 5.8 20.28 25.00 25.12 42.14 4.71 13.96 0.234
9357 2022 PAK Both 65+ 169 5.60 6.60 5.8 20.28 25.00 25.12 42.14 4.71 13.96 0.234
9358 2022 PAK Males 65+ 99 5.60 6.60 5.8 20.28 25.00 25.12 42.14 4.71 13.96 0.234
9359 2022 PAK Females 65+ 70 5.60 6.60 5.8 20.28 25.00 25.12 42.14 4.71 13.96 0.234

9360 rows × 15 columns

In [6]:
inmigrantes_merge.iloc[:, 15:]
Out[6]:
Deliberative democracy index Continent Sub-region Absence of Corruption Civil Liberties Educational equality Health equality Judicial accountability Public sector corrupt exchanges One-sided violence_deaths Non-state_deaths Intrastate_deaths Interstate_deaths Number of residents Political regime Homicide Rate Number of Turist
0 0.249 Africa Africa 0.38 0.49 0.59 0.61 0.39 0.35 0 0 345 0 51922 3 0.95 44400000
1 0.646 America South America 0.49 0.72 0.35 0.40 0.44 0.30 0 0 40 0 60185 7 5.27 44400000
2 0.646 America South America 0.49 0.72 0.35 0.40 0.44 0.30 0 0 40 0 60185 7 5.27 44400000
3 0.646 America South America 0.49 0.72 0.35 0.40 0.44 0.30 0 0 40 0 60185 7 5.27 44400000
4 0.646 America South America 0.49 0.72 0.35 0.40 0.44 0.30 0 0 40 0 60185 7 5.27 44400000
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
9355 0.301 Asia Asia 0.36 0.48 0.18 0.27 0.22 0.23 68 0 670 0 68821 6 4.21 59310000
9356 0.301 Asia Asia 0.36 0.48 0.18 0.27 0.22 0.23 68 0 670 0 31675 6 4.21 59310000
9357 0.301 Asia Asia 0.36 0.48 0.18 0.27 0.22 0.23 68 0 670 0 100496 6 4.21 59310000
9358 0.301 Asia Asia 0.36 0.48 0.18 0.27 0.22 0.23 68 0 670 0 68821 6 4.21 59310000
9359 0.301 Asia Asia 0.36 0.48 0.18 0.27 0.22 0.23 68 0 670 0 31675 6 4.21 59310000

9360 rows × 17 columns

In [7]:
# Contar datos nulos
inmigrantes_merge.isnull().sum()
Out[7]:
Year                                     0
Nationality code                         0
Sex                                      0
Age group                                0
Immigrant count                          0
Unemployment %                           0
Political and Violence Percentile        0
Probability of dying young               0
Regulatory Quality Percentile            0
Rule of Law Percentile                   0
Voice and Accountability Percentile      0
Salaried workers %                       0
GDP_growth                               0
Inflation_annual                         0
Liberal democracy index                  0
Deliberative democracy index             0
Continent                                0
Sub-region                               0
Absence of Corruption                    0
Civil Liberties                          0
Educational equality                     0
Health equality                          0
Judicial accountability                  0
Public sector corrupt exchanges          0
One-sided violence_deaths                0
Non-state_deaths                         0
Intrastate_deaths                        0
Interstate_deaths                        0
Number of residents                      0
Political regime                         0
Homicide Rate                          336
Number of Turist                         0
dtype: int64

Como observamos en la Etapa 2, no se obtuvieron datos de homicidios para Senegal más que para el año 2015, y debido a la cantidad de datos faltantes, se decidió no imputarlos ya que algunos modelos de regresión, como los basados en árboles, aceptan datos nulos. Para el caso de modelos lineales, removerá a Senegal del conjunto de datos para realizar el modelo de machine learning.

Añadido de Variables Adicionales¶

Idioma Castellano

Esta variable categórica señala si el idioma castellano es el idioma oficial de un país (sí = 1, no = 0), y con ella se busva incluir el efecto del dominio del mismo idioma hablado en España sobre la desición preferente de este destino por los inmigrantes.

In [8]:
# Cargar datos de Inflación global/anual del banco mundial
spanish_language = pd.read_excel("../3 - Paises Idioma español oficial/paises_hispanohablantes.xlsx")
spanish_language
Out[8]:
Country Country code Spanish language
0 Argentina ARG 1
1 Bolivia BOL 1
2 Chile CHL 1
3 Colombia COL 1
4 Costa Rica CRI 1
5 Cuba CUB 1
6 Ecuador ECU 1
7 El Salvador SLV 1
8 España ESP 1
9 Guatemala GTM 1
10 Guinea Ecuatorial GNQ 1
11 Honduras HND 1
12 México MEX 1
13 Nicaragua NIC 1
14 Panamá PAN 1
15 Paraguay PRY 1
16 Perú PER 1
17 Puerto Rico PR 1
18 República Dominicana DOM 1
19 Uruguay URY 1
20 Venezuela VEN 1
In [9]:
# Renombrar columna de codigo
spanish_language.rename({'Country code' : 'Nationality code'},
                        inplace = True, 
                        axis = 1)

# Eliminar columna Country
spanish_language.drop('Country', inplace = True, axis = 1)

# Unir datos a dataset de inmigrantes_merge
inmigrantes_merge = inmigrantes_merge.merge(spanish_language, on = ['Nationality code'], how = 'left')

# Remplazar nulos con "0" en Spanish_language y pasar a tipo entero
inmigrantes_merge['Spanish language'].fillna(0, inplace = True)

# Pasar columna a tipo entero y luego a objeto
inmigrantes_merge['Spanish language'] = inmigrantes_merge['Spanish language'].astype(int).astype(object)

# Verificar correcta adicion
inmigrantes_merge.groupby('Nationality code')["Spanish language"].value_counts()
Out[9]:
Nationality code  Spanish language
ARG               1                   360
BGR               0                   360
BRA               0                   360
CHN               0                   360
COL               1                   360
CUB               1                   360
DEU               0                   360
DOM               1                   360
DZA               0                   360
ECU               1                   360
FRA               0                   360
GBR               0                   360
HND               1                   360
ITA               0                   360
MAR               0                   360
NIC               1                   360
PAK               0                   360
PER               1                   360
PRT               0                   360
PRY               1                   360
ROU               0                   360
RUS               0                   360
SEN               0                   360
UKR               0                   360
USA               0                   360
VEN               1                   360
Name: count, dtype: int64

Pandemia y Post-pandemia

La variable categórica relacionada a la Pandemia señala si la presencia de restricciones sanitarias debidas al COVID durante los años 2020 y 2021 (Restricciones_pandemia = 1), y con ella se busca incluir el efecto de dichas restricciones en la variación del número de inmigrantes que llegaron a España.

Así mismo, también se incluye una variable "Año post_pandemia" para considerar la acumulación de inmigrantes durante las restricciones sanitarias entre 2020-2021, los cuáles no lograron viajar a España, y así incluir la particularidad del año 2022 al ser el primer año después de la flexibilización casi total de las restricciones.

In [10]:
# Añadir Variable Pandemia
inmigrantes_merge["Restricciones_pandemia"] = inmigrantes_merge["Year"].apply(lambda x: 1 if x==2020 or x==2021 else 0)

# Pasar a tipo objeto
inmigrantes_merge["Restricciones_pandemia"] = inmigrantes_merge["Restricciones_pandemia"].astype(object)

# Verificar adicion
inmigrantes_merge.groupby('Year')["Restricciones_pandemia"].value_counts()
Out[10]:
Year  Restricciones_pandemia
2008  0                         624
2009  0                         624
2010  0                         624
2011  0                         624
2012  0                         624
2013  0                         624
2014  0                         624
2015  0                         624
2016  0                         624
2017  0                         624
2018  0                         624
2019  0                         624
2020  1                         624
2021  1                         624
2022  0                         624
Name: count, dtype: int64
In [11]:
# Añadir Variable Post-pandemia
inmigrantes_merge["Año post_pandemia"] = inmigrantes_merge["Year"].apply(lambda x: 1 if x==2022 else 0)

# Pasar a tipo objeto
inmigrantes_merge["Año post_pandemia"] = inmigrantes_merge["Año post_pandemia"].astype(object)

# Verificar adicion
inmigrantes_merge.groupby('Year')["Año post_pandemia"].value_counts()
Out[11]:
Year  Año post_pandemia
2008  0                    624
2009  0                    624
2010  0                    624
2011  0                    624
2012  0                    624
2013  0                    624
2014  0                    624
2015  0                    624
2016  0                    624
2017  0                    624
2018  0                    624
2019  0                    624
2020  0                    624
2021  0                    624
2022  1                    624
Name: count, dtype: int64

Reducción de Variables¶

In [12]:
inmigrantes_merge.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9360 entries, 0 to 9359
Data columns (total 35 columns):
 #   Column                               Non-Null Count  Dtype  
---  ------                               --------------  -----  
 0   Year                                 9360 non-null   int64  
 1   Nationality code                     9360 non-null   object 
 2   Sex                                  9360 non-null   object 
 3   Age group                            9360 non-null   object 
 4   Immigrant count                      9360 non-null   int64  
 5   Unemployment %                       9360 non-null   float64
 6   Political and Violence Percentile    9360 non-null   float64
 7   Probability of dying young           9360 non-null   float64
 8   Regulatory Quality Percentile        9360 non-null   float64
 9   Rule of Law Percentile               9360 non-null   float64
 10  Voice and Accountability Percentile  9360 non-null   float64
 11  Salaried workers %                   9360 non-null   float64
 12  GDP_growth                           9360 non-null   float64
 13  Inflation_annual                     9360 non-null   float64
 14  Liberal democracy index              9360 non-null   float64
 15  Deliberative democracy index         9360 non-null   float64
 16  Continent                            9360 non-null   object 
 17  Sub-region                           9360 non-null   object 
 18  Absence of Corruption                9360 non-null   float64
 19  Civil Liberties                      9360 non-null   float64
 20  Educational equality                 9360 non-null   float64
 21  Health equality                      9360 non-null   float64
 22  Judicial accountability              9360 non-null   float64
 23  Public sector corrupt exchanges      9360 non-null   float64
 24  One-sided violence_deaths            9360 non-null   int64  
 25  Non-state_deaths                     9360 non-null   int64  
 26  Intrastate_deaths                    9360 non-null   int64  
 27  Interstate_deaths                    9360 non-null   int64  
 28  Number of residents                  9360 non-null   int64  
 29  Political regime                     9360 non-null   int64  
 30  Homicide Rate                        9024 non-null   float64
 31  Number of Turist                     9360 non-null   int64  
 32  Spanish language                     9360 non-null   object 
 33  Restricciones_pandemia               9360 non-null   object 
 34  Año post_pandemia                    9360 non-null   object 
dtypes: float64(18), int64(9), object(8)
memory usage: 2.5+ MB

Correlaciones¶

In [13]:
# Pasar la variable de tipo de regimen politico a objeto
inmigrantes_merge['Political regime'] = inmigrantes_merge['Political regime'].astype(object)

# Construir matriz de correlacion de variable cuantitativas
plt.figure(figsize=(30,15))
sns.heatmap(round(inmigrantes_merge.iloc[:, 4:].corr(numeric_only = True), 2), annot = True, cmap= 'coolwarm')
Out[13]:
<Axes: >

En base a los valores de correlaciones de Pearson, vemos:

  • Alta correlación entre los indices de democracia, ausencia de corrupción, "Voice and Accountability Percentile" y libertades civiles (> 0.85). Esto era de esperarse debido a que las variables están relacionadas en torno a la dimensión de derechos y actuaciones del gobierno en curso. En consecuencia, removeremos: Deliberative democracy index, Absence of Corruption, "Voice and Accountability Percentile" y Civil Liberties.
  • Alta correlacion entre equidad en salud y equidad en educación; removeremos Educational equality.
  • Alta correlación entre 'Regulatory Quality Percentile', 'Public sector corrupt exchanges', "Rule of Law", relacionadas con el sector público y la ley. Removeremos 'Regulatory Quality Percentile', 'Public sector corrupt exchanges'.
In [14]:
inmigrantes_merge.drop(['Deliberative democracy index', 'Absence of Corruption', 'Civil Liberties', 'Educational equality', 
                        'Regulatory Quality Percentile', 'Public sector corrupt exchanges','Voice and Accountability Percentile'],
                        axis = 1,
                        inplace = True)

Significancia de Variable Categóricas¶

Test de Normalidad

Evaluemos primero la normalidad de los datos de conteo inmigrantes en relacion a las distintos grupos de las variables categóricas con el test de Shapiro-Wilk con la finalidad de seleccionar un test paramétrico o no paramétrico para el contraste de hipótesis.

  • H0: Datos se ajustan a una distribución normal.
  • H1: No se ajustan a una normal.
In [15]:
# Filtrar para las categorias "Both" de sexo y "All" de los grupos de edad para realizar pruebas
inmigrantes_tests = inmigrantes_merge[(inmigrantes_merge["Sex"] != "Both") & (inmigrantes_merge["Age group"] != "All")]

# Lista de variables categóricas a testear
categorical_vars = ["Sex", "Age group", "Political regime", "Continent", "Sub-region", "Spanish language"]

# Diccionario para almacenar los grupos
grupos = {}

# Agrupar datos por las variables categóricas
for var in categorical_vars:
    grupos[var] = inmigrantes_tests.groupby([var])["Immigrant count"]

# Shapiro-Wilk test para cada grupo
for var in categorical_vars:
    print(f'------------ {var} -------------')
    for name, grupo in grupos[var]:
        stat, p = stats.shapiro(grupo)
        print(f'Group {name}: Statistics={round(stat, 4)}, p={round(p, 4)}')
    print('')
------------ Sex -------------
Group Females: Statistics=0.5497, p=0.0
Group Males: Statistics=0.5113, p=0.0

------------ Age group -------------
Group 0 - 14: Statistics=0.51, p=0.0
Group 15 - 24: Statistics=0.5864, p=0.0
Group 25 - 34: Statistics=0.5782, p=0.0
Group 35 - 44: Statistics=0.5288, p=0.0
Group 45 - 54: Statistics=0.5587, p=0.0
Group 55 - 64: Statistics=0.5923, p=0.0
Group 65+: Statistics=0.5947, p=0.0

------------ Political regime -------------
Group 0: Statistics=0.9071, p=0.0
Group 1: Statistics=0.6338, p=0.0
Group 2: Statistics=0.7825, p=0.0
Group 3: Statistics=0.6483, p=0.0
Group 6: Statistics=0.4623, p=0.0
Group 7: Statistics=0.6851, p=0.0

------------ Continent -------------
Group Africa: Statistics=0.5627, p=0.0
Group America: Statistics=0.5001, p=0.0
Group Asia: Statistics=0.8624, p=0.0
Group Europe: Statistics=0.5974, p=0.0

------------ Sub-region -------------
Group Africa: Statistics=0.5627, p=0.0
Group Asia: Statistics=0.8624, p=0.0
Group Central America and Caribbean: Statistics=0.6921, p=0.0
Group European Union: Statistics=0.6436, p=0.0
Group North America: Statistics=0.8568, p=0.0
Group Rest of Europe: Statistics=0.4896, p=0.0
Group South America: Statistics=0.5279, p=0.0

------------ Spanish language -------------
Group 0: Statistics=0.5476, p=0.0
Group 1: Statistics=0.5098, p=0.0

A partir de los resultados de p-valor, rechazamos la hipotesis nula H0 con un nivel de confianza de 95% (p-valor < 0.05), es decir, los datos no siguen una disibución normal; resultado que se esperaba considerando nuestro análisis inicial de los datos de inmigración durante la Etapa 1.

En consecuencia, usaremos el test no paramétricos U de Mann-Whitney (para dos grupos) y Kruskal-Wallis para aquellas variables con múltiples grupos.

Prueba U de Mann-Whitney y Prueba de Kruskal-Wallis

  • H0: No hay diferencia (en términos de tendencia central) entre los grupos.
  • H1: Existe una diferencia (con respecto a la tendencia central) entre los grupos.
In [16]:
# Variables para Mann-Whitney U test (dos grupos)
mann_whitney_vars = {
    "Sex": ["Males", "Females"],
    "Spanish language": [0, 1]
}

# Variables para Kruskal-Wallis test (mas de dos grupo)
kruskal_wallis_vars = {
    "Age group": ['0 - 14', '15 - 24', '25 - 34', '35 - 44', '45 - 54', '55 - 64', '65+'],
    "Political regime": [0, 1, 2, 3, 6, 7],
    "Continent": ['Africa', 'Asia', 'America', 'Europe'],
    "Sub-region": ['Africa', 'Asia', 'Central America and Caribbean', 'European Union', 'North America', 'Rest of Europe', 'South America']
}

# Iterar variables con dos grupos para la prueba de Mann-Whitney
for var, groups in mann_whitney_vars.items():
    print(f'------------------ Variable "{var}" -------------------- \n')
    stat, p = stats.mannwhitneyu(inmigrantes_merge[inmigrantes_merge[var] == groups[0]]["Immigrant count"],
                                 inmigrantes_merge[inmigrantes_merge[var] == groups[1]]["Immigrant count"])
    print(f'Prueba U de Mann-Whitney: Statistics={round(stat, 4)}, p={round(p, 4)} \n')

# Iterar variables con más de dospara la prueba de Kruskal-Wallis test
for var, groups in kruskal_wallis_vars.items():
    print(f'------------------ Variable "{var}" -------------------- \n')
    group_data = [inmigrantes_merge[inmigrantes_merge[var] == group]["Immigrant count"] for group in groups]
    stat, p = stats.kruskal(*group_data)
    print(f'Prueba Kruskal-Wallis: Statistics={round(stat, 4)}, p={round(p, 4)} \n')
------------------ Variable "Sex" -------------------- 

Prueba U de Mann-Whitney: Statistics=4641572.5, p=0.0015 

------------------ Variable "Spanish language" -------------------- 

Prueba U de Mann-Whitney: Statistics=10816393.0, p=0.0004 

------------------ Variable "Age group" -------------------- 

Prueba Kruskal-Wallis: Statistics=2726.2587, p=0.0 

------------------ Variable "Political regime" -------------------- 

Prueba Kruskal-Wallis: Statistics=365.6376, p=0.0 

------------------ Variable "Continent" -------------------- 

Prueba Kruskal-Wallis: Statistics=116.0261, p=0.0 

------------------ Variable "Sub-region" -------------------- 

Prueba Kruskal-Wallis: Statistics=260.0816, p=0.0 

Para todas las variables rechazamos la hipótesis nula H0 (p-valor < 0.05), es decir, la número de inmigracion de mujeres y hombres difieren y, para las variables con más de dos grupos, al menos dos de ellos difieren. En consecuencia, no removeremos ninguna de las variables categóricas de nuestros datos.

Veamos la distribución con boxplots para las dos variables copn solo 2 grupos: "Sex" y "Spanish language".

In [17]:
# Función para graficar distribucion de datos de cantidad de inmigrantes en boxplots segun grupos de variables categóricas
def boxplot_grupos(datos, variable):
    """
    Función que realiza un boxplot horizontal de número de inmigrantes por grupos
    con la librería Altair a partir de los siguientes parámetros:
    
    - datos: origen de los datos
    - variable (string): variable categórica (ej: 'Age group')
    """
    return alt.Chart(datos, height=30, width=1000).mark_boxplot().encode(
        x=alt.X('Immigrant count:Q', title="Número de Inmigrantes"),
        row=alt.Row(variable, header=alt.Header(labelAngle=-360, labelAlign='left')),
        tooltip=["Nationality code", 'Year']
    ).properties(title=f'{variable}')

# Boxplots por grupos de las variables "Sex" y "Spanish language"
boxplot_grupos(inmigrantes_tests, "Sex").display()
boxplot_grupos(inmigrantes_tests, "Spanish language").display()

A través de los boxplots es dificil establecer diferencias en la tendencia central entre los sexos y países con el castellano como idioma oficial. En el caso se sexo, puede deberse a que se observa una mayor disperción en los datos de cantidad de inmigrantes hombres, similar a lo que se observa en el grupo de idioma castellano.

Ahora bien, veamos cuales grupon difieren entre sí para las variables que presentan mas de 2 grupos usando el test de Dunn de comparasión multiple:

  • H0: No hay diferencias entre los dos grupos.
  • H1: Existe una diferencia entre dos grupos.

Simplifiquemos la vista de resultados de la matriz de p-valores para una comparación mas sencilla.

In [18]:
# Funcion para simplificar los la matriz de resultados de la prueba de Dunn e indicar diferencia "Sí" o "No"
def simplificar_resultados_dunn(dunn_resultados):
    simplified_results = dunn_resultados.stack().reset_index()
    simplified_results.columns = ['Grupo 1', 'Grupo 2', 'p-valor']
    # Evitar que se repitan grupos ya comparados
    simplified_results = simplified_results[simplified_results['Grupo 1'] != simplified_results['Grupo 2']]
    simplified_results = simplified_results[simplified_results['Grupo 1'] < simplified_results['Grupo 2']]
    # Agregar columna para especificar si hay o no diferencias significativas
    simplified_results['Diferencias?'] = simplified_results['p-valor'].apply(lambda x: 'Si' if x < 0.05 else 'No')
    return simplified_results

# Lista de variables
variables = ['Age group', 'Political regime', 'Continent', 'Sub-region']

# Realizar test de Dunn en cada variable, mostrar resultados de las comparasiones pareadas y exportar tabla
with pd.option_context('expand_frame_repr', False): # expandir las columnas del output
    for var in variables:
        print(f'------------------ Variable "{var}" -------------------- \n')
        dunn_resultados = sp.posthoc_dunn(inmigrantes_tests, 
                                  val_col="Immigrant count", 
                                  group_col=var, 
                                  p_adjust='bonferroni')
        print('Prueba de comparación múltiple de Dunn: \n', simplificar_resultados_dunn(dunn_resultados), "\n")

        # Exportar resultados como csv
        simplificar_resultados_dunn(dunn_resultados).to_csv(f"../14 - Exports (resultados prueba de dunn)/{var}_resultados_dunn.csv", 
                                                            index=False,
                                                            encoding = 'utf-8')
------------------ Variable "Age group" -------------------- 

Prueba de comparación múltiple de Dunn: 
     Grupo 1  Grupo 2        p-valor Diferencias?
1    0 - 14  15 - 24   1.665376e-08           Si
2    0 - 14  25 - 34   1.306032e-29           Si
3    0 - 14  35 - 44   1.000000e+00           No
4    0 - 14  45 - 54   2.604809e-20           Si
5    0 - 14  55 - 64   1.580498e-73           Si
6    0 - 14      65+  3.218532e-110           Si
9   15 - 24  25 - 34   1.262778e-06           Si
10  15 - 24  35 - 44   3.759252e-05           Si
11  15 - 24  45 - 54   3.129615e-54           Si
12  15 - 24  55 - 64  1.019143e-130           Si
13  15 - 24      65+  1.972534e-178           Si
17  25 - 34  35 - 44   4.420449e-23           Si
18  25 - 34  45 - 54   1.109330e-97           Si
19  25 - 34  55 - 64  1.017288e-194           Si
20  25 - 34      65+  3.724038e-252           Si
25  35 - 44  45 - 54   1.835213e-26           Si
26  35 - 44  55 - 64   7.314785e-85           Si
27  35 - 44      65+  5.203596e-124           Si
33  45 - 54  55 - 64   4.458760e-17           Si
34  45 - 54      65+   1.113573e-36           Si
41  55 - 64      65+   7.395364e-04           Si 

------------------ Variable "Political regime" -------------------- 

Prueba de comparación múltiple de Dunn: 
     Grupo 1  Grupo 2       p-valor Diferencias?
1         0        1  5.797419e-01           No
2         0        2  3.210212e-17           Si
3         0        3  4.248195e-04           Si
4         0        6  7.591952e-02           No
5         0        7  1.000000e+00           No
8         1        2  6.458774e-13           Si
9         1        3  3.568171e-13           Si
10        1        6  3.733542e-09           Si
11        1        7  3.723511e-01           No
15        2        3  1.941724e-51           Si
16        2        6  6.597457e-47           Si
17        2        7  1.306699e-28           Si
22        3        6  1.231845e-01           No
23        3        7  4.400942e-18           Si
29        6        7  9.474825e-14           Si 

------------------ Variable "Continent" -------------------- 

Prueba de comparación múltiple de Dunn: 
     Grupo 1  Grupo 2       p-valor Diferencias?
1    Africa  America  1.000000e+00           No
2    Africa     Asia  1.000000e+00           No
3    Africa   Europe  1.622303e-12           Si
6   America     Asia  1.000000e+00           No
7   America   Europe  6.567824e-21           Si
11     Asia   Europe  1.564577e-10           Si 

------------------ Variable "Sub-region" -------------------- 

Prueba de comparación múltiple de Dunn: 
                           Grupo 1                        Grupo 2       p-valor Diferencias?
1                          Africa                           Asia  1.000000e+00           No
2                          Africa  Central America and Caribbean  8.473527e-03           Si
3                          Africa                 European Union  5.513440e-12           Si
4                          Africa                  North America  4.335915e-03           Si
5                          Africa                 Rest of Europe  3.437238e-06           Si
6                          Africa                  South America  4.321137e-05           Si
9                            Asia  Central America and Caribbean  1.339112e-01           No
10                           Asia                 European Union  3.131845e-10           Si
11                           Asia                  North America  2.679378e-02           Si
12                           Asia                 Rest of Europe  9.000989e-06           Si
13                           Asia                  South America  1.362301e-04           Si
17  Central America and Caribbean                 European Union  6.837387e-33           Si
18  Central America and Caribbean                  North America  1.000000e+00           No
19  Central America and Caribbean                 Rest of Europe  1.363378e-18           Si
20  Central America and Caribbean                  South America  3.059028e-20           Si
25                 European Union                  North America  4.315470e-17           Si
26                 European Union                 Rest of Europe  1.000000e+00           No
27                 European Union                  South America  1.389210e-02           Si
33                  North America                 Rest of Europe  2.579185e-12           Si
34                  North America                  South America  3.186092e-11           Si
41                 Rest of Europe                  South America  1.000000e+00           No 

Para los grupos de edades, observamos que únicamente los grupos de 0-14 años y 35-44 años no tienen diferencias significativas, el resto sí. Veamos la distribución de inmigrantes por grupo con boxplots:

In [19]:
# Boxplots de Cantidad de Inmigrantes por grupo de edad
boxplot_grupos(inmigrantes_tests, "Age group").display()

Es dificil observar tendencias debido a la cantidad de datos atípicos, pero si nos enfocamos en las cajas y bigotes de las cajas junto a la concentración de datos atípicos, puede distinguirse la diferencias en la tendencia central detectada por el test de Dunn para casi todos los grupos, menos entre 0-14 y 35-44 años.

En cuanto a los tipos de régimen político, resalta el régimen tipo 2 (autocracias multipartidistas sin ejecutivo electo) es significativamente diferente al resto, resultado que se refleja claramente en el boxplot (ver gráfico abajo). De forma similar, el régimen tipo 3 (autocracias multipartidistas) también presentó diferencias con los demás tipos de regímenes, exceptuando el tipo 6 (democracias electorales).

In [20]:
# Boxplots de Cantidad de Inmigrantes por régimen político
boxplot_grupos(inmigrantes_tests, "Political regime").display()

El continente europeo fue el único que presentó diferencias significativas con el resto de los continentes.

En contraste con los continentes, las subregiones presentan una mayor cantidad de diferencias significativas Vemos a América del Norte que se diferencia de todos menos con el Caribe-Centro América. De forma similar, la UE y América del Sur también difieren con todos, exceptuando a “el resto de Europa”.

In [21]:
# Boxplots de Cantidad de Inmigrantes por continente
boxplot_grupos(inmigrantes_tests, "Continent").display()
In [22]:
# Boxplots de Cantidad de Inmigrantes por sub-región
boxplot_grupos(inmigrantes_tests, "Sub-region").display()

A razón estas observaciones, no se removeran ninguna de las variables categóricas del conjunto de datos para la construcción del modelo de machine learning (referirse a los notebooks de "Etapa 4").

In [37]:
# Exportar conjunto de datos final con todas las variables seleccionadas
inmigrantes_merge.to_csv("../13 - Exports (preprocesamiento)/inmigrantes_merge.csv", index = False)